package cn.jellybmedia.user.service.impl;

import cn.jellybmedia.basic.constant.BaseConstants;
import cn.jellybmedia.basic.exception.BusinessException;
import cn.jellybmedia.basic.utils.MD5Utils;
import cn.jellybmedia.basic.utils.StrUtils;
import cn.jellybmedia.basic.vo.RegisterVo;
import cn.jellybmedia.user.domain.Logininfo;
import cn.jellybmedia.user.domain.User;
import cn.jellybmedia.user.mapper.LogininfoMapper;
import cn.jellybmedia.user.mapper.UserMapper;
import cn.jellybmedia.user.service.IUserService;
import cn.jellybmedia.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ChuengXu
 * @since 2022-07-05
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LogininfoMapper logininfoMapper;

    /**======================================================================================
    * @Title: registerPhone
    * @Description: 手机号注册实现方法
    * @Author: Mr.Zhang
    * @Version: 1.0
    * @Date:  2022/7/6 16:03
    * @Parameters: [registerVo]
    * @Return void
    ======================================================================================*/
    @Override
    public void registerPhone(RegisterVo registerVo) {
        String phone = registerVo.getPhone(); //手机号
        String smsCodeValue = registerVo.getSmsCodeValue(); // 手机验证码
        String password = registerVo.getPassword(); //密码
        String confirmPassword = registerVo.getConfirmPassword(); // 确认密码

        // 判断参数是否为空
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(smsCodeValue) || StringUtils.isEmpty(password) || StringUtils.isEmpty(confirmPassword) ){
            throw new BusinessException("参数不能为空");
        }

        // 判断两次手机号是否一致
        // 先获取上一次的手机号,需要用时间戳解出来
        String phoneCodeKey = BaseConstants.RegisterCodeConstants.BUSINESS_REGISTER_PREFIX + phone;
        Object phoneCodeValue = redisTemplate.opsForValue().get(phoneCodeKey);
        if (phoneCodeValue == null) {
            throw new BusinessException("验证码已过期,请重新获取验证码");
        }

        // 判断验证码是否正确
        String phoneCode = phoneCodeValue.toString().split(":")[1];
        if (!phoneCode.equalsIgnoreCase(smsCodeValue)){
            throw new BusinessException("验证码不正确,请重新输入验证码");
        }

        // 判断两次密码是否一致
        if (!password.equals(confirmPassword)){
            throw new BusinessException("两次密码不一致,请检查后输入");
        }

        // 判断用户是否已注册，如果已注册提示用户
        User user = userMapper.loadByPhone(phone);
        if (user != null){
            throw new BusinessException("用户已注册，请直接登录！");
        }

        // 初始化User表,用户注册后给一些字段进行赋值操作
        user = smsCodeDto2User(registerVo);
        // 添加user用户
        userMapper.save(user);

        // 初始话logininfo表.直接把User表的东西copy过去,因为字段一样
        Logininfo logininfo = user2Logininfo(user);
        // 添加logininfo表
        logininfoMapper.save(logininfo);

        // 进行修改user表.因为user表有一个登录账号字段.是logininfo字段
        user.setLogininfoId(logininfo.getId());
        userMapper.update(user);
    }

    /**======================================================================================
     * @Title: registerEmail
     * @Description: 邮箱注册方法
     * @Author: Mr.Zhang
     * @Version: 1.0
     * @Date:  2022/7/6 18:59
     * @Parameters: [registerVo]
     * @Return void
    ======================================================================================*/
    @Override
    public void registerEmail(RegisterVo registerVo) {
        String email = registerVo.getEmail(); //邮箱号
        String smsCodeValue = registerVo.getSmsCodeValue(); // 邮箱验证码
        String password = registerVo.getPassword(); //密码
        String confirmPassword = registerVo.getConfirmPassword(); // 确认密码
        

        // 判断参数是否为空
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(smsCodeValue) || StringUtils.isEmpty(password) || StringUtils.isEmpty(confirmPassword) ){
            throw new BusinessException("参数不能为空");
        }

        // 判断两次手机号是否一致
        // 先获取上一次的手机号,需要用时间戳解出来
        String phoneCodeKey = BaseConstants.RegisterCodeConstants.BUSINESS_REGISTER_PREFIX + email;
        Object phoneCodeValue = redisTemplate.opsForValue().get(phoneCodeKey);
        if (phoneCodeValue == null) {
            throw new BusinessException("验证码已过期,请重新获取验证码");
        }

        // 判断验证码是否正确
        String phoneCode = phoneCodeValue.toString().split(":")[1];
        if (!phoneCode.equalsIgnoreCase(smsCodeValue)){
            throw new BusinessException("验证码不正确,请重新输入验证码");
        }

        // 判断两次密码是否一致
        if (!password.equals(confirmPassword)){
            throw new BusinessException("两次密码不一致,请检查后输入");
        }

        // 判断用户是否已注册，如果已注册提示用户
        User user = userMapper.loadByPhone(email);
        if (user != null){
            throw new BusinessException("用户已注册，请直接登录！");
        }

        // 初始化User表,用户注册后给一些字段进行赋值操作
        user = smsCodeDto2User(registerVo);
        // 添加user用户
        userMapper.save(user);

        // 初始话logininfo表.直接把User表的东西copy过去,因为字段一样
        Logininfo logininfo = user2Logininfo(user);
        // 添加logininfo表
        logininfoMapper.save(logininfo);

        // 进行修改user表.因为user表有一个登录账号字段.是logininfo字段
        user.setLogininfoId(logininfo.getId());
        userMapper.update(user);
    }




    /**======================================================================================
    * @Title: user2Logininfo
    * @Description: 把值设置进去Logininfo表中
    * @Author: Mr.Zhang
    * @Version: 1.0
    * @Date:  2022/7/6 16:02
    * @Parameters: [user]
    * @Return cn.jellybmedia.user.domain.Logininfo
    ======================================================================================*/
    private Logininfo user2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
        // 设置账号为用户.0为管理员.1为用户
        logininfo.setType(1);
        return logininfo;
    }


    /**======================================================================================
    * @Title: smsCodeDto2User
    * @Description: 把值设置进去User表中
    * @Author: Mr.Zhang
    * @Version: 1.0
    * @Date:  2022/7/6 16:02
    * @Parameters: [registerVo]
    * @Return cn.jellybmedia.user.domain.User
    ======================================================================================*/
    private User smsCodeDto2User(RegisterVo registerVo) {
        // 获取注册手机号
        String phone = registerVo.getPhone();

        // 获取注册邮箱号
        String email = registerVo.getEmail();

        // 因为通过手机号注册,没有用户名字段,所以设置用户名字段与手机号字段一样
        User user = new User();

        if (registerVo.getPhone() != null){
            user.setUsername(phone);
            user.setPhone(phone);
        }else if (registerVo.getEmail() != null){
            user.setUsername(email);
            user.setEmail(email);
        }

        // 给密码加盐值,并设置盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 设置密码加密加盐
        String password = MD5Utils.encrypByMd5(salt +registerVo.getPassword());
        // 设置进去
        user.setPassword(password);
        user.setSalt(salt);
        return user;
    }



}
